<template>
  <PageWrapper title="WebSocket 示例">
    <div class="flex">
      <div class="w-1/3 bg-white p-4">
        <div class="flex items-center">
          <span class="text-lg font-medium mr-4"> 连接状态: </span>
          <Tag :color="getTagColor">{{ status }}</Tag>
        </div>
        <hr class="my-4" />

        <div class="flex">
          <a-input v-model:value="server" disabled>
            <template #addonBefore> 服务地址 </template>
          </a-input>
          <a-button :type="getIsOpen ? 'danger' : 'primary'" @click="toggle">
            {{ getIsOpen ? '关闭连接' : '开启连接' }}
          </a-button>
        </div>
        <p class="text-lg font-medium mt-4">设置</p>
        <hr class="my-4" />

        <InputTextArea placeholder="需要发送到服务器的内容" :disabled="!getIsOpen" v-model:value="sendValue" allowClear />

        <a-button type="primary" block class="mt-4" :disabled="!getIsOpen" @click="handlerSend"> 发送 </a-button>
      </div>

      <div class="w-2/3 bg-white ml-4 p-4">
        <span class="text-lg font-medium mr-4"> 消息记录: </span>
        <hr class="my-4" />

        <div class="max-h-80 overflow-auto">
          <ul>
            <li v-for="item in getList" class="mt-2" :key="item.time">
              <div class="flex items-center">
                <span class="mr-2 text-primary font-medium">收到消息:</span>
                <span>{{ formatToDateTime(item.time) }}</span>
              </div>
              <div>
                {{ item.res }}
              </div>
            </li>
          </ul>
        </div>
      </div>
    </div>
  </PageWrapper>
</template>
<script lang="ts">
import { defineComponent, reactive, watchEffect, computed, toRefs } from 'vue';
import { Tag, Input } from 'ant-design-vue';
import { PageWrapper } from '/@/components/Page';
import { useWebSocket } from '@vueuse/core';
import { formatToDateTime } from '/@/utils/dateUtil';

export default defineComponent({
  components: {
    PageWrapper,
    [Input.name]: Input,
    InputTextArea: Input.TextArea,
    Tag,
  },
  setup() {
    const state = reactive({
      server: 'ws://localhost:8080/test',
      sendValue: '',
      recordList: [] as { id: number; time: number; res: string }[],
    });

    const { status, data, send, close, open } = useWebSocket(state.server, {
      autoReconnect: false,
      heartbeat: true,
    });

    watchEffect(() => {
      if (data.value) {
        try {
          const res = JSON.parse(data.value);
          state.recordList.push(res);
        } catch (error) {
          state.recordList.push({
            res: data.value,
            id: Math.ceil(Math.random() * 1000),
            time: new Date().getTime(),
          });
        }
      }
    });

    const getIsOpen = computed(() => status.value === 'OPEN');
    const getTagColor = computed(() => (getIsOpen.value ? 'success' : 'red'));

    const getList = computed(() => {
      return [...state.recordList].reverse();
    });

    function handlerSend() {
      send(state.sendValue);
      state.sendValue = '';
    }

    function toggle() {
      if (getIsOpen.value) {
        close();
      } else {
        open();
      }
    }
    return {
      status,
      formatToDateTime,
      ...toRefs(state),
      handlerSend,
      getList,
      toggle,
      getIsOpen,
      getTagColor,
    };
  },
});
</script>
